package com.gzc.just.play.last.war.centralserver.leaderboard;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 排行榜管理器 - 管理所有排行榜数据
 * 
 * @author AI编程助手
 * @version 1.0
 */
public class LeaderboardManager {
    
    private final Map<LeaderboardType, SortedSet<LeaderboardEntry>> leaderboards = new ConcurrentHashMap<>();
    private final Map<Long, LeaderboardEntry> playerEntries = new ConcurrentHashMap<>();
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final List<LeaderboardListener> listeners = new CopyOnWriteArrayList<>();
    
    private long lastUpdateTime = 0;
    private static final long UPDATE_INTERVAL = 60000; // 1分钟更新一次排名
    
    /**
     * 构造函数
     */
    public LeaderboardManager() {
        // 初始化所有排行榜
        for (LeaderboardType type : LeaderboardType.values()) {
            leaderboards.put(type, Collections.synchronizedSortedSet(new TreeSet<>()));
        }
    }
    
    /**
     * 更新玩家分数
     * 
     * @param playerId 玩家ID
     * @param playerName 玩家名称
     * @param scoreIncrease 分数增加量
     */
    public void updatePlayerScore(long playerId, String playerName, long scoreIncrease) {
        lock.writeLock().lock();
        try {
            LeaderboardEntry entry = playerEntries.get(playerId);
            
            if (entry == null) {
                // 创建新条目
                entry = new LeaderboardEntry(playerId, playerName, scoreIncrease);
                playerEntries.put(playerId, entry);
                leaderboards.get(LeaderboardType.SCORE_RANKING).add(entry);
            } else {
                // 更新分数
                long oldScore = entry.getScore();
                entry.addScore(scoreIncrease);
                
                // 重新排序
                SortedSet<LeaderboardEntry> scoreRanking = leaderboards.get(LeaderboardType.SCORE_RANKING);
                scoreRanking.remove(entry);
                scoreRanking.add(entry);
            }
            
            updateRankings();
            notifyPlayerScoreUpdated(playerId, entry.getScore());
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 更新玩家战斗结果
     * 
     * @param playerId 玩家ID
     * @param playerName 玩家名称
     * @param win 是否胜利
     * @param kills 击杀数
     * @param deaths 死亡数
     * @param scoreGain 获得的分数
     */
    public void updateBattleResult(long playerId, String playerName, boolean win, int kills, int deaths, long scoreGain) {
        lock.writeLock().lock();
        try {
            LeaderboardEntry entry = playerEntries.get(playerId);
            
            if (entry == null) {
                entry = new LeaderboardEntry(playerId, playerName, scoreGain);
                playerEntries.put(playerId, entry);
                for (LeaderboardType type : LeaderboardType.values()) {
                    leaderboards.get(type).add(entry);
                }
            } else {
                entry.addScore(scoreGain);
            }
            
            // 更新战斗统计
            if (win) {
                entry.addWin();
            } else {
                entry.addLoss();
            }
            
            if (kills > 0) {
                entry.addKills(kills);
            }
            if (deaths > 0) {
                entry.addDeaths(deaths);
            }
            
            // 重新排序所有排行榜
            for (LeaderboardType type : LeaderboardType.values()) {
                SortedSet<LeaderboardEntry> ranking = leaderboards.get(type);
                ranking.remove(entry);
                ranking.add(entry);
            }
            
            updateRankings();
            notifyBattleResultUpdated(playerId, win, kills, deaths, scoreGain);
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 获取排行榜前N条记录
     * 
     * @param type 排行榜类型
     * @param topCount 前N条
     * @return 排行榜条目列表
     */
    public List<LeaderboardEntry> getTopEntries(LeaderboardType type, int topCount) {
        lock.readLock().lock();
        try {
            SortedSet<LeaderboardEntry> ranking = leaderboards.get(type);
            if (ranking == null) {
                return new ArrayList<>();
            }
            
            List<LeaderboardEntry> result = new ArrayList<>();
            int count = 0;
            for (LeaderboardEntry entry : ranking) {
                if (count >= topCount) {
                    break;
                }
                result.add(entry);
                count++;
            }
            return result;
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 获取玩家在排行榜上的排名
     * 
     * @param type 排行榜类型
     * @param playerId 玩家ID
     * @return 排名（从1开始，0表示未在排行榜上）
     */
    public int getPlayerRank(LeaderboardType type, long playerId) {
        lock.readLock().lock();
        try {
            LeaderboardEntry entry = playerEntries.get(playerId);
            if (entry == null) {
                return 0;
            }
            return entry.getRank();
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 获取玩家排行榜条目
     * 
     * @param playerId 玩家ID
     * @return 排行榜条目
     */
    public LeaderboardEntry getPlayerEntry(long playerId) {
        lock.readLock().lock();
        try {
            return playerEntries.get(playerId);
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 获取排行榜大小
     * 
     * @param type 排行榜类型
     * @return 条目数
     */
    public int getLeaderboardSize(LeaderboardType type) {
        lock.readLock().lock();
        try {
            SortedSet<LeaderboardEntry> ranking = leaderboards.get(type);
            return ranking != null ? ranking.size() : 0;
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 更新所有排名
     */
    private void updateRankings() {
        for (LeaderboardType type : LeaderboardType.values()) {
            SortedSet<LeaderboardEntry> ranking = leaderboards.get(type);
            int rank = 1;
            for (LeaderboardEntry entry : ranking) {
                entry.setRank(rank++);
            }
        }
    }
    
    /**
     * 添加监听器
     * 
     * @param listener 监听器
     */
    public void addListener(LeaderboardListener listener) {
        if (listener != null) {
            listeners.add(listener);
        }
    }
    
    /**
     * 移除监听器
     * 
     * @param listener 监听器
     */
    public void removeListener(LeaderboardListener listener) {
        listeners.remove(listener);
    }
    
    private void notifyPlayerScoreUpdated(long playerId, long newScore) {
        for (LeaderboardListener listener : listeners) {
            listener.onPlayerScoreUpdated(playerId, newScore);
        }
    }
    
    private void notifyBattleResultUpdated(long playerId, boolean win, int kills, int deaths, long scoreGain) {
        for (LeaderboardListener listener : listeners) {
            listener.onBattleResultUpdated(playerId, win, kills, deaths, scoreGain);
        }
    }
    
    /**
     * 排行榜监听器接口
     */
    public interface LeaderboardListener {
        void onPlayerScoreUpdated(long playerId, long newScore);
        void onBattleResultUpdated(long playerId, boolean win, int kills, int deaths, long scoreGain);
    }
}
